package sistemadeproyectos;

import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.Image;
import javax.swing.BorderFactory;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.*;
import java.sql.*;
import java.net.*;
import java.io.*;

/**
 *
 * @author Giancarlo Nebiolo, 06-39956
 * @author Antonio Mundo, 06-39965
 * @author Angel Rubio, 06-40263
 */
public class MapaMental extends javax.swing.JFrame {

    private Usuario usuarioActivo;
    private Equipo equipoActual;
    private LinkedList<JLabel> etiquetas;
    private LinkedList<JPanel> formas;
    private boolean creandoImagen = false;
    private boolean creandoForma = false;
    private Socket conexion;
    private ObjectInputStream entrada;
    private ObjectOutputStream salida;
    
    /** Creates new form MapaMental */
    public MapaMental(Usuario elUsuario, Equipo elEquipo) throws IOException{
        initComponents();
        this.etiquetas = new LinkedList <JLabel>();
        this.formas = new LinkedList<JPanel>();
        ServersConf rutas = new ServersConf();
        this.usuarioActivo = elUsuario;
        this.equipoActual = elEquipo;
        try {
            //Se crea la conexión con el serivor de Repositorio
            this.conexion = new Socket (rutas.getIPRepositorio(), rutas.getPuertoRepositorio());
            this.entrada = new ObjectInputStream ((this.conexion).getInputStream());
            this.salida = new ObjectOutputStream ((this.conexion).getOutputStream());
            this.salida.writeObject(elUsuario.getUsuario());
            this.salida.writeObject(elEquipo.getIdEquipo());
            ArrayList<String> recibido = (ArrayList<String>)(this.entrada).readObject();
        }
        catch (IOException e) { 
            JOptionPane.showMessageDialog(this, "Error al establecer conexion con servidor.", 
                "Error en Conexion", JOptionPane.ERROR_MESSAGE);
            limpiar_socket();
            //e.printStackTrace();
            this.dispose();
            throw e;
        }
        catch(ClassNotFoundException cnfe){
            cnfe.printStackTrace();
        }
    }

    public void setUsuario(Usuario elUsuario){
        this.usuarioActivo = elUsuario;
    }
    
    public void setEquipo(Equipo elEquipo){
        this.equipoActual = elEquipo;
    }
    
    private void limpiar_socket() {
        try { 
          (this.entrada).close();
          (this.salida).close();
          (this.conexion).close();
        }
        catch (Exception e) {
            //e.printStackTrace();
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        crearImagen = new javax.swing.JButton();
        eliminarElemento = new javax.swing.JButton();
        modificarElemento = new javax.swing.JButton();
        jpnlLienzo = new javax.swing.JPanel();
        crearForma = new javax.swing.JButton();
        lblEstado = new javax.swing.JLabel();
        jbtnGuardar = new javax.swing.JButton();
        jbtnReconstruir = new javax.swing.JButton();
        jbtnCerrar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(sistemadeproyectos.SistemadeproyectosApp.class).getContext().getResourceMap(MapaMental.class);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });

        crearImagen.setText(resourceMap.getString("crearImagen.text")); // NOI18N
        crearImagen.setName("crearImagen"); // NOI18N
        crearImagen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                crearImagenActionPerformed(evt);
            }
        });

        eliminarElemento.setText(resourceMap.getString("eliminarElemento.text")); // NOI18N
        eliminarElemento.setName("eliminarElemento"); // NOI18N
        eliminarElemento.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                eliminarElementoActionPerformed(evt);
            }
        });

        modificarElemento.setText(resourceMap.getString("modificarElemento.text")); // NOI18N
        modificarElemento.setName("modificarElemento"); // NOI18N
        modificarElemento.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modificarElementoActionPerformed(evt);
            }
        });

        jpnlLienzo.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jpnlLienzo.setName("jpnlLienzo"); // NOI18N
        jpnlLienzo.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jpnlLienzoMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout jpnlLienzoLayout = new javax.swing.GroupLayout(jpnlLienzo);
        jpnlLienzo.setLayout(jpnlLienzoLayout);
        jpnlLienzoLayout.setHorizontalGroup(
            jpnlLienzoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 753, Short.MAX_VALUE)
        );
        jpnlLienzoLayout.setVerticalGroup(
            jpnlLienzoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 436, Short.MAX_VALUE)
        );

        crearForma.setText(resourceMap.getString("crearForma.text")); // NOI18N
        crearForma.setName("crearForma"); // NOI18N
        crearForma.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                crearFormaActionPerformed(evt);
            }
        });

        lblEstado.setFont(resourceMap.getFont("lblEstado.font")); // NOI18N
        lblEstado.setText(resourceMap.getString("lblEstado.text")); // NOI18N
        lblEstado.setName("lblEstado"); // NOI18N

        jbtnGuardar.setText(resourceMap.getString("jbtnGuardar.text")); // NOI18N
        jbtnGuardar.setToolTipText(resourceMap.getString("jbtnGuardar.toolTipText")); // NOI18N
        jbtnGuardar.setName("jbtnGuardar"); // NOI18N
        jbtnGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnGuardarActionPerformed(evt);
            }
        });

        jbtnReconstruir.setText(resourceMap.getString("jbtnReconstruir.text")); // NOI18N
        jbtnReconstruir.setName("jbtnReconstruir"); // NOI18N
        jbtnReconstruir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnReconstruirActionPerformed(evt);
            }
        });

        jbtnCerrar.setText(resourceMap.getString("jbtnCerrar.text")); // NOI18N
        jbtnCerrar.setName("jbtnCerrar"); // NOI18N
        jbtnCerrar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnCerrarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(51, 51, 51)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(crearImagen, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(crearForma, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(eliminarElemento, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jbtnCerrar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jbtnReconstruir, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jbtnGuardar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(modificarElemento, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(46, 46, 46)
                        .addComponent(jpnlLienzo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(23, 23, 23)
                        .addComponent(lblEstado)))
                .addContainerGap(50, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(71, 71, 71)
                        .addComponent(crearImagen)
                        .addGap(18, 18, 18)
                        .addComponent(crearForma)
                        .addGap(18, 18, 18)
                        .addComponent(eliminarElemento)
                        .addGap(18, 18, 18)
                        .addComponent(modificarElemento)
                        .addGap(18, 18, 18)
                        .addComponent(jbtnGuardar)
                        .addGap(18, 18, 18)
                        .addComponent(jbtnReconstruir)
                        .addGap(18, 18, 18)
                        .addComponent(jbtnCerrar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 145, Short.MAX_VALUE)
                        .addComponent(lblEstado))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(29, 29, 29)
                        .addComponent(jpnlLienzo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private String pasarURL(String URL){
        String nuevaURL = "";
        if(System.getProperty("os.name").substring(0,5).equals("Windo")){
            int i = 0;
            while(i < URL.length()){
                nuevaURL = nuevaURL + URL.charAt(i);
                if((""+URL.charAt(i)).equals("\\")){
                    nuevaURL = nuevaURL + URL.charAt(i);
                }
                i++;
            }
            //System.out.println("Final: " + nuevaURL);
        }
        else{
            nuevaURL = URL;
        }
        return nuevaURL;
    }
    
    private ImageIcon ajustarImagen(String ico, int ancho, int alto) {
        ImageIcon tmpIconAux = new ImageIcon(ico);
        //Escalar Imagen
        ImageIcon tmpIcon = new ImageIcon(tmpIconAux.getImage().getScaledInstance(ancho, alto, Image.SCALE_DEFAULT));
        return tmpIcon;
    }
    
    public void reconstruirMapa(){
        //Se eliminan todos los elementos presentes en el lienzo actual
        for(int i = this.etiquetas.size() - 1; i >= 0;  i--){
            this.jpnlLienzo.remove(this.etiquetas.get(i));
            this.etiquetas.remove(i);
            this.repaint();
        }
        for(int i = this.formas.size() - 1; i >= 0; i--){           
            this.jpnlLienzo.remove(this.formas.get(i));
            this.formas.remove(i);
            this.repaint();
        }
        //Se agregan los elementos que se listan en la base de datos
        BDAdmin motor = new BDAdmin("SELECT * FROM ELEMENTO_MAPA_MENTAL WHERE EQUIPO = '" + this.equipoActual.getIdEquipo() + "'");
        ResultSet rs = motor.consulta();
        try{
            while(rs.next()){
                String tipo = rs.getString("COD_ELEM").substring(0, 5);
                if(tipo.equals("Image")){
                    //Se crea un jLabel nuevo y se inserta en la lista
                    String dir = rs.getString("URL_IMAGEN");
                    String suTexto = rs.getString("TEXTO");
                    String nombre = rs.getString("COD_ELEM");
                    int elX = rs.getInt("POSX");
                    int elY = rs.getInt("POSY");
                    int elAncho = rs.getInt("ANCHO");
                    int elAlto = rs.getInt("ALTO") - 30;
                    Imagen laImagen = new Imagen(nombre, suTexto, elX, elY, elAncho, elAlto,"",dir);
                    ImagenJLabel imagen = new ImagenJLabel(laImagen);
                    imagen.addMouseMotionListener(new ratonDinamico(imagen, this.etiquetas,null,this.formas));
                    imagen.addMouseListener(new ratonEstatico(imagen, this.etiquetas,null,this.formas));
                    imagen.setName(nombre);
                    this.etiquetas.add(imagen);
                    //Se configura la imagen y el texto del JLabel
                    imagen.setBounds(elX, elY, elAncho, elAlto);
                    
                    try{
                        (this.salida).writeObject("imagen");
                        (this.salida).writeObject(dir);
                        (this.salida).writeObject(imagen.getWidth()+"");
                        (this.salida).writeObject(imagen.getHeight()+"");
                        ImageIcon resultImagen = (ImageIcon)(this.entrada).readObject();
                        imagen.setIcon(resultImagen);
                    }
                    catch(IOException ioe){
                        ioe.printStackTrace();
                    }
                    catch(ClassNotFoundException cnfe){
                        cnfe.printStackTrace();
                    }
                    
                    imagen.setToolTipText(suTexto);
                    imagen.setText(suTexto);
                    imagen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
                    imagen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
                    //Se agrega el JLabel al JPanel
                    imagen.setSize(imagen.getWidth(),imagen.getHeight()+30);
                    jpnlLienzo.add(imagen);
                    this.repaint();
                }
                else if(tipo.equals("Forma")){
                    String nombre = rs.getString("COD_ELEM");
                    String elTexto = rs.getString("TEXTO");
                    int suAncho = rs.getInt("ANCHO")-25;
                    int suAlto = rs.getInt("ALTO")-25;
                    int elX = rs.getInt("POSX");
                    int elY = rs.getInt("POSY");
                    Color suColorFondo = new Color (rs.getInt("COLOR_FONDO"));
                    Color suColorLinea = new Color(rs.getInt("COLOR_LINEA"));
                    Font laFuente = new Font(rs.getString("FUENTE_NOMBRE"), rs.getInt("FUENTE_EST"), rs.getInt("FUENTE_TAM"));
                    int laForma = rs.getInt("TIPO_FIGURA");
                    Forma objeto = new Forma(nombre, elTexto, elX, elY, suAncho, suAlto, laForma, suColorLinea, suColorFondo, laFuente,"");
                    FigurasJPanel panelx = new FigurasJPanel(objeto);
                    panelx.setBounds(elX, elY, suAncho+25, suAlto+25);
                    panelx.addMouseMotionListener(new ratonDinamico(null,this.etiquetas,panelx,this.formas));
                    panelx.addMouseListener(new ratonEstatico(null,this.etiquetas,panelx,this.formas));
                    this.formas.add(panelx);
                    panelx.setName(nombre);
                    jpnlLienzo.add(panelx);
                    this.repaint();
                }
            }
        }
        catch(SQLException sqle){
            sqle.printStackTrace();
        }
    }
    
    private void crearImagenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_crearImagenActionPerformed
        // TODO add your handling code here:
        this.creandoImagen = true;
        lblEstado.setText("Haga clic en el recuadro para insertar la imagen");
    }//GEN-LAST:event_crearImagenActionPerformed
    
    private void modificarElementoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modificarElementoActionPerformed
        // TODO add your handling code here:        
        for(int i = 0; i < this.etiquetas.size(); i++){
            if(this.etiquetas.get(i).getBorder() != null){
                ImagenVentana dialogoImagen = new ImagenVentana(this, true);
                dialogoImagen.setEquipo(this.equipoActual);
                dialogoImagen.setUsuario(this.usuarioActivo);
                dialogoImagen.setConexion();
                dialogoImagen.setTexto(this.etiquetas.get(i).getText());
                dialogoImagen.setAlto((this.etiquetas.get(i).getHeight()-30)+"");
                dialogoImagen.setAncho(this.etiquetas.get(i).getWidth()+"");
                dialogoImagen.setURL(((ImagenJLabel)this.etiquetas.get(i)).getURLImagen());
                
                dialogoImagen.setVisible(true);
                if(dialogoImagen.aceptar == true){
                    String nuevoTexto = dialogoImagen.texto;
                    this.etiquetas.get(i).setToolTipText(nuevoTexto);
                    this.etiquetas.get(i).setText(nuevoTexto);
                    this.etiquetas.get(i).setSize(dialogoImagen.ancho, dialogoImagen.alto+30);
                    
                    try{
                        (this.salida).writeObject("imagen");
                        (this.salida).writeObject(dialogoImagen.URLImagen);
                        (this.salida).writeObject(this.etiquetas.get(i).getWidth()+"");
                        (this.salida).writeObject((this.etiquetas.get(i).getHeight()-30)+"");
                        ImageIcon resultImagen = (ImageIcon)(this.entrada).readObject();
                        this.etiquetas.get(i).setIcon(resultImagen);
                    }
                    catch(IOException ioe){
                        ioe.printStackTrace();
                    }
                    catch(ClassNotFoundException cnfe){
                        cnfe.printStackTrace();
                    }
                    
                    //this.etiquetas.get(i).setIcon(ajustarImagen(dialogoImagen.URLImagen, this.etiquetas.get(i).getWidth(), this.etiquetas.get(i).getHeight()-30 ));                    
                    ((ImagenJLabel)this.etiquetas.get(i)).setURLImagen(dialogoImagen.URLImagen);
                }                
                this.repaint();
            }
        }
        for(int i = 0; i < this.formas.size(); i++){
            if(this.formas.get(i).getBorder() != null){
                FormaVentana dialogoForma = new FormaVentana(this, true);
                dialogoForma.setForma(((FigurasJPanel)this.formas.get(i)).getForma().getFigura());
                dialogoForma.setColorLinea(((FigurasJPanel)this.formas.get(i)).getForma().getColorLinea());
                dialogoForma.setColorFondo(((FigurasJPanel)this.formas.get(i)).getForma().getColorFondo());
                dialogoForma.setTexto(((FigurasJPanel)this.formas.get(i)).getForma().getTexto());
                dialogoForma.setFuente(((FigurasJPanel)this.formas.get(i)).getForma().getFuente());
                dialogoForma.setAlto((this.formas.get(i).getHeight()-25)+"");
                dialogoForma.setAncho((this.formas.get(i).getWidth()-25)+"");
                dialogoForma.setVisible(true);
                if(dialogoForma.aceptar == true){
                    Font laFuente = dialogoForma.fuenteFinal;
                    String elTexto = dialogoForma.textoFinal;
                    int laForma = dialogoForma.formaFinal;
                    Color suColorLinea = dialogoForma.colorLinea;
                    Color suColorFondo = dialogoForma.colorFondo;
                    int suAlto = dialogoForma.alto;
                    int suAncho = dialogoForma.ancho;
                    int elX = this.formas.get(i).getX();
                    int elY = this.formas.get(i).getY();
                    Forma objeto = new Forma(this.formas.get(i).getName(), elTexto, elX, elY, suAncho, suAlto, laForma, suColorLinea, suColorFondo, laFuente,"");                  
                    ((FigurasJPanel)this.formas.get(i)).setForma(objeto);
                    ((FigurasJPanel)this.formas.get(i)).reDibujar(elTexto, laFuente);
                    this.formas.get(i).setSize(suAncho+25, suAlto+25);
                }                
                this.repaint();
            }
        }
    }//GEN-LAST:event_modificarElementoActionPerformed

    private void eliminarElementoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_eliminarElementoActionPerformed
        // TODO add your handling code here:
        int pregunta;
        for(int i = 0; i < this.etiquetas.size(); i++){
            if(this.etiquetas.get(i).getBorder() != null){
                pregunta = JOptionPane.showConfirmDialog(this, "¿Desea eliminar esta imagen?", "Eliminar elemento", JOptionPane.YES_NO_OPTION);
                if (pregunta == JOptionPane.YES_OPTION){
                    jpnlLienzo.remove(this.etiquetas.get(i));
                    this.etiquetas.remove(i);
                    this.repaint();
                }
            }
        }
        for(int i = 0; i < this.formas.size(); i++){
            if(this.formas.get(i).getBorder() != null){
                pregunta = JOptionPane.showConfirmDialog(this, "¿Desea eliminar esta imagen?", "Eliminar elemento", JOptionPane.YES_NO_OPTION);
                if (pregunta == JOptionPane.YES_OPTION){
                    jpnlLienzo.remove(this.formas.get(i));
                    this.formas.remove(i);
                    this.repaint();
                }
            }
        }
    }//GEN-LAST:event_eliminarElementoActionPerformed

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        // TODO add your handling code here:
        this.repaint();
    }//GEN-LAST:event_formComponentResized

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        // TODO add your handling code here:
    }//GEN-LAST:event_formMouseClicked

    private void jpnlLienzoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jpnlLienzoMouseClicked
        // TODO add your handling code here:
        if(creandoImagen == true){
            ImagenVentana dialogoImagen = new ImagenVentana(this, true);
            dialogoImagen.setEquipo(this.equipoActual);
            dialogoImagen.setUsuario(this.usuarioActivo);
            dialogoImagen.setConexion();
            dialogoImagen.setVisible(true);
            if (dialogoImagen.aceptar == true){
                //Se crea un jLabel nuevo y se inserta en la lista
                String dir = dialogoImagen.URLImagen;
                String suTexto = dialogoImagen.texto;
                String nombre = "Imagen"+etiquetas.size();
                Imagen laImagen = new Imagen(nombre, suTexto, evt.getX()-(dialogoImagen.ancho/2), evt.getY()-(dialogoImagen.alto/2),dialogoImagen.ancho, dialogoImagen.alto,"",dir);
                ImagenJLabel imagen = new ImagenJLabel(laImagen);
                imagen.addMouseMotionListener(new ratonDinamico(imagen, this.etiquetas,null,this.formas));
                imagen.addMouseListener(new ratonEstatico(imagen, this.etiquetas,null,this.formas));
                imagen.setName(nombre);
                this.etiquetas.add(imagen);
                //Se configura la imagen y el texto del JLabel
                imagen.setBounds(evt.getX()-(dialogoImagen.ancho/2), evt.getY()-(dialogoImagen.alto/2), dialogoImagen.ancho, dialogoImagen.alto);
                
                try{
                    (this.salida).writeObject("imagen");
                    (this.salida).writeObject(dir);
                    (this.salida).writeObject(imagen.getWidth()+"");
                    (this.salida).writeObject(imagen.getHeight()+"");
                    ImageIcon resultImagen = (ImageIcon)(this.entrada).readObject();
                    imagen.setIcon(resultImagen);
                }
                catch(IOException ioe){
                    ioe.printStackTrace();
                }
                catch(ClassNotFoundException cnfe){
                    cnfe.printStackTrace();
                }
                
                imagen.setToolTipText(suTexto);
                imagen.setText(suTexto);
                imagen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
                imagen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
                //Se agrega el JLabel al JPanel
                imagen.setSize(imagen.getWidth(),imagen.getHeight()+30);
                jpnlLienzo.add(imagen);
                this.repaint();
                //Se retiran todos los enfoques
                for(int i = 0; i < this.etiquetas.size(); i++){
                    this.etiquetas.get(i).setBorder(null);
                }
                for(int i = 0; i < this.formas.size(); i++){
                   this.formas.get(i).setBorder(null);
                }
                //Se le da el enfoque a la nueva imagen
                imagen.setBorder(BorderFactory.createLineBorder(Color.blue));    
            }
            //Se termina el proceso de creacion
            creandoImagen = false;
            lblEstado.setText("Estado:");
        }
        else if (creandoForma == true){
            FormaVentana dialogoForma = new FormaVentana(this, true);
            dialogoForma.setVisible(true);
            if(dialogoForma.aceptar == true){
                Font laFuente = dialogoForma.fuenteFinal;
                String nombre = "Forma" + this.formas.size();
                String elTexto = dialogoForma.textoFinal;
                int laForma = dialogoForma.formaFinal;
                Color suColorLinea = dialogoForma.colorLinea;
                Color suColorFondo = dialogoForma.colorFondo;
                int suAlto = dialogoForma.alto;
                int suAncho = dialogoForma.ancho;
                Forma objeto = new Forma(nombre, elTexto, evt.getX(), evt.getY(), suAncho, suAlto, laForma, suColorLinea, suColorFondo, laFuente,"");
                FigurasJPanel panelx = new FigurasJPanel(objeto);
                panelx.setBounds(evt.getX(), evt.getY(), suAncho+25, suAlto+25);
                panelx.addMouseMotionListener(new ratonDinamico(null,this.etiquetas,panelx,this.formas));
                panelx.addMouseListener(new ratonEstatico(null,this.etiquetas,panelx,this.formas));
                this.formas.add(panelx);
                panelx.setName(nombre);
                jpnlLienzo.add(panelx);
                //Se retiran todos los enfoques
                for(int i = 0; i < this.etiquetas.size(); i++){
                    this.etiquetas.get(i).setBorder(null);
                }
                for(int i = 0; i < this.formas.size(); i++){
                    this.formas.get(i).setBorder(null);
                }
                //Se le da el enfoque a la nueva forma
                panelx.setBorder(BorderFactory.createLineBorder(Color.blue));    
            }
            //Se termina el proceso de creacion
            creandoForma = false;
            lblEstado.setText("Estado:");
        }
        else{
            for(int i = 0; i < this.etiquetas.size(); i++){
                this.etiquetas.get(i).setBorder(null);
            }
            for(int i = 0; i < this.formas.size(); i++){
                this.formas.get(i).setBorder(null);
            }
        }
    }//GEN-LAST:event_jpnlLienzoMouseClicked

    private void crearFormaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_crearFormaActionPerformed
        // TODO add your handling code here:
        this.creandoForma = true;
        lblEstado.setText("Haga clic en el recuadro para insertar la forma");
    }//GEN-LAST:event_crearFormaActionPerformed

    private void jbtnGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnGuardarActionPerformed
        // TODO add your handling code here:
        BDAdmin motor = new BDAdmin("");
        int i = 0;
        for(i = 0; i < this.formas.size(); i++){
            String elNombre = this.formas.get(i).getName();
            String elUsuario = this.usuarioActivo.getUsuario();
            String elEquipo = this.equipoActual.getIdEquipo();
            String elTexto = ((FigurasJPanel)this.formas.get(i)).getForma().getTexto();
            int elAncho = this.formas.get(i).getWidth();
            int elAlto = this.formas.get(i).getHeight();
            int elX = this.formas.get(i).getX();
            int elY = this.formas.get(i).getY();
            int elColorFondo = ((FigurasJPanel)this.formas.get(i)).getForma().getColorFondo().getRGB();
            int elColorLinea = ((FigurasJPanel)this.formas.get(i)).getForma().getColorLinea().getRGB();
            String laFuente = ((FigurasJPanel)this.formas.get(i)).getForma().getFuente().getFontName();
            int tamFuente = ((FigurasJPanel)this.formas.get(i)).getForma().getFuente().getSize();
            int estFuente = ((FigurasJPanel)this.formas.get(i)).getForma().getFuente().getStyle();
            int laForma = ((FigurasJPanel)this.formas.get(i)).getForma().getFigura();
            motor.setQuery("SELECT * FROM ELEMENTO_MAPA_MENTAL WHERE EQUIPO = '" + elEquipo + "' AND COD_ELEM = '" + elNombre + "'");
            try{
                ResultSet rs = motor.consulta();
                if (rs.next() == true){
                    if(!(rs.getString("USUARIO").equals(elUsuario)) || !(rs.getString("TEXTO").equals(elTexto))
                            || rs.getInt("ANCHO") != elAncho || rs.getInt("ALTO") != elAlto || 
                            rs.getInt("POSX") != elX || rs.getInt("POSY") != elY || rs.getInt("COLOR_FONDO") != elColorFondo
                            || rs.getInt("COLOR_LINEA") != elColorLinea || !(rs.getString("FUENTE_NOMBRE").equals(laFuente)) 
                            || rs.getInt("FUENTE_TAM") != tamFuente || rs.getInt("FUENTE_EST") != estFuente || rs.getInt("TIPO_FIGURA") != laForma ){
                        motor.setQuery("UPDATE ELEMENTO_MAPA_MENTAL SET USUARIO = '" + elUsuario + "', TEXTO = '" + elTexto + "', ANCHO = "  + elAncho + ", ALTO = " + elAlto + ", POSX = " + elX + ", POSY = " + elY + ", COLOR_FONDO = " + elColorFondo + ", COLOR_LINEA = " + elColorLinea + ", FUENTE_NOMBRE = '" + laFuente + "', FUENTE_TAM = " + tamFuente + ", FUENTE_EST = " + estFuente + ", TIPO_FIGURA = " + laForma + "WHERE EQUIPO = '" + elEquipo + "' AND COD_ELEM = '" + elNombre + "'");
                        motor.actualizar();
                    }
                }
                else{
                    motor.setQuery("INSERT INTO ELEMENTO_MAPA_MENTAL VALUES ('" + elNombre + "','" + elUsuario + "','" + elEquipo + "','" + elTexto + "'," + elAncho + "," + elAlto + "," + elX + "," + elY + "," + elColorFondo + "," + elColorLinea + ",'" + laFuente + "'," + tamFuente + "," + estFuente + "," + laForma + ", NULL)");
                    motor.actualizar();
                }
            }
            catch(SQLException sqle){
                sqle.printStackTrace();
            }
        }
        for(i = 0; i < this.etiquetas.size(); i++){
            String elNombre = this.etiquetas.get(i).getName();
            String elUsuario = this.usuarioActivo.getUsuario();
            String elEquipo = this.equipoActual.getIdEquipo();
            String elTexto = this.etiquetas.get(i).getText();
            int elAncho = this.etiquetas.get(i).getWidth();
            int elAlto = this.etiquetas.get(i).getHeight();
            int elX = this.etiquetas.get(i).getX();
            int elY = this.etiquetas.get(i).getY();
            String laURLImagen = ((ImagenJLabel)this.etiquetas.get(i)).getURLImagen();
            motor.setQuery("SELECT * FROM ELEMENTO_MAPA_MENTAL WHERE EQUIPO = '" + elEquipo + "' AND COD_ELEM = '" + elNombre + "'");
            try{
                ResultSet rs = motor.consulta();
                if (rs.next() == true){
                    if(!(rs.getString("USUARIO").equals(elUsuario)) || !(rs.getString("TEXTO").equals(elTexto))
                            || rs.getInt("ANCHO") != elAncho || rs.getInt("ALTO") != elAlto || 
                            rs.getInt("POSX") != elX || rs.getInt("POSY") != elY || !(rs.getString("URL_IMAGEN").equals(laURLImagen)) ){
                        motor.setQuery("UPDATE ELEMENTO_MAPA_MENTAL SET USUARIO = '" + elUsuario + "', TEXTO = '" + elTexto + "', ANCHO = "  + elAncho + ", ALTO = " + elAlto + ", POSX = " + elX + ", POSY = " + elY + ", URL_IMAGEN = '" + pasarURL(laURLImagen) + "' WHERE EQUIPO = '" + elEquipo + "' AND COD_ELEM = '" + elNombre + "'");
                        motor.actualizar();
                    }
                }
                else{
                    motor.setQuery("INSERT INTO ELEMENTO_MAPA_MENTAL VALUES ('" + elNombre + "','" + elUsuario + "','" + elEquipo + "','" + elTexto + "'," + elAncho + "," + elAlto + "," + elX + "," + elY + ", NULL, NULL, NULL, NULL, NULL, NULL,'" + pasarURL(laURLImagen) + "')");
                    motor.actualizar();
                }
            }
            catch(SQLException sqle){
                sqle.printStackTrace();
            }
        }
        
        motor.setQuery("SELECT * FROM ELEMENTO_MAPA_MENTAL WHERE EQUIPO = '" + this.equipoActual.getIdEquipo() + "'");
        ResultSet sensor = motor.consulta();
        try{
            while(sensor.next()){
                String unNombre = sensor.getString("COD_ELEM");
                boolean encontrado = false;
                for(i = 0; i < this.etiquetas.size(); i++){
                    if(unNombre.equals(this.etiquetas.get(i).getName())){
                        encontrado = true;
                    }
                }
                for(i = 0; i < this.formas.size(); i++){
                    if(unNombre.equals(this.formas.get(i).getName())){
                        encontrado = true;
                    }
                }
                if(encontrado == false){
                    motor.setQuery("DELETE FROM ELEMENTO_MAPA_MENTAL WHERE EQUIPO = '" + this.equipoActual.getIdEquipo() + "' AND COD_ELEM = '" + unNombre + "'");
                    motor.actualizar();
                }
            }
            JOptionPane.showMessageDialog(this, "El mapa ha sido guardado exitosamente." ,
               "Guardado exitoso", JOptionPane.INFORMATION_MESSAGE);
        }
        catch(SQLException sqle){
            JOptionPane.showMessageDialog(this, "El mapa no pudo ser guardado." ,
               "Error al guardar", JOptionPane.ERROR_MESSAGE);
            sqle.printStackTrace();
        }
        
        motor.cerrar();
    }//GEN-LAST:event_jbtnGuardarActionPerformed

    private void jbtnReconstruirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnReconstruirActionPerformed
        // TODO add your handling code here:
        reconstruirMapa();
    }//GEN-LAST:event_jbtnReconstruirActionPerformed

    private void jbtnCerrarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnCerrarActionPerformed
        // TODO add your handling code here:
        try{
            (this.salida).writeObject("salir");
        }
        catch(IOException ioe){}
        limpiar_socket();
        this.dispose();
    }//GEN-LAST:event_jbtnCerrarActionPerformed

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        // TODO add your handling code here:
    }//GEN-LAST:event_formWindowClosed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        // TODO add your handling code here:
        try{
            (this.salida).writeObject("salir");
        }
        catch(IOException ioe){}
        limpiar_socket();
    }//GEN-LAST:event_formWindowClosing

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                //new MapaMental().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton crearForma;
    private javax.swing.JButton crearImagen;
    private javax.swing.JButton eliminarElemento;
    private javax.swing.JButton jbtnCerrar;
    private javax.swing.JButton jbtnGuardar;
    private javax.swing.JButton jbtnReconstruir;
    private javax.swing.JPanel jpnlLienzo;
    private javax.swing.JLabel lblEstado;
    private javax.swing.JButton modificarElemento;
    // End of variables declaration//GEN-END:variables
}

class ratonEstatico implements MouseListener{
    JLabel etiqueta;
    JPanel panel;
    LinkedList<JLabel> listaEtiquetas;
    LinkedList<JPanel> listaPaneles;
    
    public ratonEstatico(JLabel imagen, LinkedList<JLabel> lista, JPanel elpanel, LinkedList<JPanel> listaP){
        this.etiqueta = imagen;
        this.listaEtiquetas = lista;
        this.panel = elpanel;
        this.listaPaneles = listaP;
    }
    
    public void mouseClicked(MouseEvent e) {
        int i = 0;
        if(this.etiqueta != null){
            for(i = 0; i < this.listaEtiquetas.size(); i++){
                this.listaEtiquetas.get(i).setBorder(null);
            }
            for(i = 0; i < this.listaPaneles.size(); i++){
                this.listaPaneles.get(i).setBorder(null);
            }
            etiqueta.setBorder(BorderFactory.createLineBorder(Color.blue));
        }
        else if (this.panel != null){
            for(i = 0; i < this.listaEtiquetas.size(); i++){
                this.listaEtiquetas.get(i).setBorder(null);
            }
            for(i = 0; i < this.listaPaneles.size(); i++){
                this.listaPaneles.get(i).setBorder(null);
            }
            panel.setBorder(BorderFactory.createLineBorder(Color.blue));
        }
    }
    
    public void mouseExited (MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
}

class ratonDinamico implements MouseMotionListener{
    JLabel etiqueta;
    JPanel panel;
    LinkedList<JLabel> listaEtiquetas;
    LinkedList<JPanel> listaPaneles;
    
    public ratonDinamico(JLabel imagen, LinkedList<JLabel> listaE, JPanel elpanel, LinkedList<JPanel> listaP){
        this.etiqueta = imagen;
        this.listaEtiquetas = listaE;
        this.panel = elpanel;
        this.listaPaneles = listaP;
        
    }
    public void mouseDragged(java.awt.event.MouseEvent evt) {
        int i = 0;
        if(this.etiqueta != null){
            for(i = 0; i < this.listaEtiquetas.size(); i++){
                this.listaEtiquetas.get(i).setBorder(null);
            }
            for(i = 0; i < this.listaPaneles.size(); i++){
                this.listaPaneles.get(i).setBorder(null);
            }
            etiqueta.setBorder(BorderFactory.createLineBorder(Color.blue));
            etiqueta.setLocation(
                etiqueta.getX() + evt.getX() - etiqueta.getWidth() / 2,
                etiqueta.getY() + evt.getY() - etiqueta.getHeight() / 2);
            //etiqueta.actualizarImagen();
        }
        else if (this.panel != null){
            for(i = 0; i < this.listaEtiquetas.size(); i++){
                this.listaEtiquetas.get(i).setBorder(null);
            }
            for(i = 0; i < this.listaPaneles.size(); i++){
                this.listaPaneles.get(i).setBorder(null);
            }
            panel.setBorder(BorderFactory.createLineBorder(Color.blue));
            panel.setLocation(
                panel.getX() + evt.getX() - panel.getWidth() / 2,
                panel.getY() + evt.getY() - panel.getHeight() / 2);
            ((FigurasJPanel)panel).actualizarForma();
        }
    }
    
    public void mouseMoved  (MouseEvent e) {}
}

class FigurasJPanel extends JPanel{
    
    private Forma formaPanel;
    private JLabel texto;
    
    public FigurasJPanel(Forma laForma){
        this.formaPanel = laForma;
        this.setLayout(null);
        this.texto = new JLabel(laForma.getTexto());
        this.texto.setFont(laForma.getFuente());
        //OJO: setBounds(x, y, ancho, alto);
        this.texto.setBounds(10, laForma.getAlto()/3, laForma.getAncho(), 50);
        this.texto.setHorizontalAlignment(JTextField.CENTER);
        this.add(texto);        
    }
    
    // dibuja figuras con la API Java2D
    @Override
    public void paintComponent( Graphics g ){
        super.paintComponent( g ); //Llama al método paintComponent de la superclase
        Graphics2D g2d = ( Graphics2D ) g; //Convierte a g en objeto Graphics2D
        if (this.formaPanel.getFigura() == Forma.ELIPSE){
            //Dibuja el contorno de la elipse
            g2d.setPaint(this.formaPanel.getColorLinea());
            g2d.setStroke(new BasicStroke(10.0f,java.awt.BasicStroke.CAP_BUTT,java.awt.BasicStroke.JOIN_BEVEL,2 ) );
            //Dibuja el fondo de la elipse
            g2d.draw(new Ellipse2D.Double(10, 10, this.formaPanel.getAncho(), this.formaPanel.getAlto()));
            g2d.setPaint(this.formaPanel.getColorFondo());
            g2d.fill(new Ellipse2D.Double(10, 10, this.formaPanel.getAncho(), this.formaPanel.getAlto()));
        }
        else if(this.formaPanel.getFigura() == Forma.RECTANGULO){
            //Dibuja el contorno del rectángulo
            g2d.setPaint(this.formaPanel.getColorLinea());
            g2d.setStroke(new BasicStroke(10.0f,java.awt.BasicStroke.CAP_BUTT,java.awt.BasicStroke.JOIN_BEVEL,2 ) );
            g2d.draw(new Rectangle2D.Double(10, 10, this.formaPanel.getAncho(), this.formaPanel.getAlto()));
            //Dibuja el fondo del rectangulo
            g2d.setPaint(this.formaPanel.getColorFondo());
            g2d.setStroke(new BasicStroke(10.0f));
            g2d.fill(new Rectangle2D.Double(10, 10, this.formaPanel.getAncho(), this.formaPanel.getAlto()));
        }
    }
    
    public void reDibujar(String texto, Font fuente){
        this.paintComponent(this.getGraphics());
        this.texto.setBounds(10, this.formaPanel.getAlto()/3, this.formaPanel.getAncho(), 50);
        this.texto.setText(texto);
        this.texto.setFont(fuente);
    }
    
    public Forma getForma(){
        return this.formaPanel;
    }
    
    public void setForma(Forma laForma){
        this.formaPanel = laForma;
    }
    
    public void actualizarForma(){
        this.formaPanel.setPosx(this.getX());
        this.formaPanel.setPosy(this.getY());
    }
}

class ImagenJLabel extends JLabel{

    private Imagen contenido;
        
    public ImagenJLabel(Imagen laImagen){
        this.contenido = laImagen;
    }
    
    public void setURLImagen(String urlImagen){
        this.contenido.setULRImagen(urlImagen);
    }
    
    public String getURLImagen(){
        return this.contenido.getULRImagen();
    }
    
}
